# -*- coding: utf-8 -*-
from os import getenv

from loguru import logger
import json
import sys

from prometheus_client import (
    push_to_gateway,
    CollectorRegistry, Counter, Gauge)


def format_user(up): return \
    f"[{(user := up.from_user).id}] {user.first_name} {user.last_name or ''}"


def command(data, up):
    metrics.set('Telegram_Command')
    return logger.info(f"{format_user(up)} [Command {data}]")


def message(data, up):
    metrics.set('Telegram_Message')
    return logger.info(f"{format_user(up)} [Message {data}]")


def keyboard(data, up):
    metrics.set('Telegram_Keyboard')
    return logger.info(f"{format_user(up)} [Keyboard {data}]")


def iQuery(data, up):
    metrics.set('Telegram_iQuery')
    return logger.info(f"{format_user(up)} [iQuery {data or '*empty*'}]")


def iResult(data, up):
    metrics.set('Telegram_iResult')
    return logger.info(f"{format_user(up)} [iResult {data}]")


def joins(user, data, chat): return logger.info(
    f"[{user.id}] {user.first_name} {user.last_name or ''} {data} {chat.title} [{chat.id}]")


def MySQL(variable): return logger.debug(
    f"[MySQL] {variable}")


def MongoDB(database: str, table: str, parameters: list): return logger.debug(
    f"[MongoDB] {database}.{table}\n" + "\n".join(f"{parameter}" for parameter in parameters))


def HTTP(http: str, url: str, data: dict): return logger.debug(
    f"[HTTP.{http.upper()}] {url}\n" + "\n".join(f"{key_value[0]}={key_value[1]}" for key_value in data.items()))


def sink(message):
    print(json.dumps({
        'facility': getenv('Facility'),
        'text': message.__str__(),
        '@timestamp': (record := message.record)['time'],
        'elapsed': {
            'repr': record['elapsed'],
            'seconds': record['elapsed'].total_seconds()},
        'level': record['level'].no,
        'level_name': record['level'].name,
        'file': {'name': record['file'].name, 'path': record['file'].path},
        'thread': {'id': record['thread'].id, 'name': record['thread'].name},
        'process': {'id': record['process'].id, 'name': record['process'].name},
        **{key: record[key] for key in (
            'module', 'function', 'line', 'exception', 'name', 'message', 'extra')}
    }, default=str, ensure_ascii=False))


logger.configure(handlers=[
    {'level': 'INFO',
     'format': "{time:%d.%m.%Y %X} [{level}] {message}   {file}, line {line} in {function}()",
     'sink': sink}
    if getenv('Facility', 'Test') != 'Test' else
    {'level': 'INFO',
     'format': "{time:%X} [{level}] {message}",
     'sink': sys.stdout}
])


class Metrics(object):
    def __init__(self, job: str, graphs: dict, registry: CollectorRegistry):
        self.graphs = graphs
        self.registry = registry
        self.job = job

    def set(self, key: str, value=0.5, **kwargs):
        if isinstance(self.graphs[key], Counter):
            self.graphs[key].inc(value)
        if isinstance(self.graphs[key], Gauge):
            self.graphs[key].labels(**kwargs).set(value)

    # @logger.catch()
    def push(self):
        # push_to_gateway('10.0.0.9:9091', job=self.job, registry=self.registry)
        logger.debug("Metrics ✅")


metrics = Metrics(job=getenv('Facility'), registry=(registry_ := CollectorRegistry()), graphs={
    f'Telegram_{request}': Counter(f'Telegram_{request}', f"Кол-во Telegram-запросов вида {request}", registry=registry_)
    for request in ('Command', 'Message', 'Keyboard', 'iQuery', 'iResult')
})
